﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SuperSocket.SocketBase.Protocol;
using SuperSocket.SocketBase;
using LogLib;
using SocketServer.ServerBase;
using IUploading;

namespace SocketServer
{
    /// <summary>
    ///  代表监听客户端连接，承载TCP连接的服务器实例。
    ///  理想情况下，我们可以通过AppServer实例获取任何你想要的客户端连接，
    ///  服务器级别的操作和逻辑应该定义在此类之中。       
    /// </summary>
    public class TransferServer : AppServer<ClientRequestPackSession, BinaryRequestInfo>, IServer
    {
        protected string _error = "";
        public string ErrorMessage
        {
            get
            {
                return _error;
            }
        }

        /// <summary>
        /// 指示服务器是否已经启动
        /// </summary>
        public bool Running
        {
            get { return this.State == ServerState.Running; }
        }

        //缓冲字节数组
        private byte[] buffer = new byte[2048];

        public Dictionary<string, IUpload> Uploaders
        {
            get;
            set;
        }

        /// <summary>
        /// 当前活动的会话
        /// </summary>
        public ClientRequestPackSession ActivedSession
        {
            get;
            set;
        }

        /// <summary>
        /// 启动或登录失败的接口列表
        /// </summary>
        private List<KeyValuePair<string, string>> listInitFailedInterfaces = new List<KeyValuePair<string, string>>();

        /// <summary>
        /// 存储session和对应ip端口号的泛型集合
        /// </summary>
        public Dictionary<string, ClientRequestPackSession> SessionList = new Dictionary<string, ClientRequestPackSession>();

        public event TransferResponsedEventHandler TransferResponsed;
        public void ReportTransferReponse(TransferResponsePackge packge)
        {
            if (TransferResponsed != null)
            {
                TransferResponsed(this, new TransferResponsedEventArgs(packge));
            }
        }

        public event TransferTimeoutEventHandler TransferTimeout;
        public void OnTransferTimeout(string message)
        {
            if (TransferTimeout != null)
            {
                TransferTimeout(this, new TransferTimeoutEventArgs(message));
            }
        }

        public event Action AppExited;
        public void OnAppExited(string inParams)
        {
            if (AppExited != null)
            {
                AppExited();
            }
        }

        private LocalServerConfig _config = new LocalServerConfig();

        public TransferServer()
            : base(new ClientRequestPackReceiveFilterFactory())
        {
            
        }

        public event NewSessionRequestReceivedHandler NewSessionRequestReceived;
        public void OnNewSessionRequestReceived(ClientRequestPackSession session, TransferDataPackge pack)
        {
            ActivedSession = session;
            if (NewSessionRequestReceived != null)
            {
                NewSessionRequestReceived(session, pack);
            }
        }

        public bool Init()
        {
            var config = new SuperSocket.SocketBase.Config.ServerConfig()
            {
                Name = _config.Name,
                ServerTypeName = _config.Name,
                ClearIdleSession = _config.ClearIdleSession, // 300秒执行一次清理300秒没数据传送的连接
                ClearIdleSessionInterval = _config.ClearIdleSessionInterval,
                IdleSessionTimeOut = _config.IdleSessionTimeOut,
                MaxRequestLength = _config.MaxRequestLength, //最大包长度
                Ip = _config.Ip,
                Port = _config.Port,
                MaxConnectionNumber = _config.MaxConnectionNumber,
            };
            if (this.State == ServerState.NotInitialized)
            {
                if (Setup(config))
                {
                    string info = string.Format("{0}初始化成功, IP:{1}, port:{2}", _config.Name, _config.Ip, _config.Port);
                    Log.WriteAsync(info);
                    return true;                
                }
                else
                {
                    _error = "Failed to Setup:" + _config.Name; ;
                    Log.WriteAsync(_error);
                    return false;
                }
            }
            return true;
        }

        public bool StartServer()
        {
            if (this.Running)
            {
                return true;
            }
            if (this.State == ServerState.NotStarted)
            {
                if (Start())
                {
                    return true;
                }
                else
                {
                    _error = "Failed to Start";
                    Log.WriteAsync(_error);
                    return false;
                }
            }
            return true;        
        }

        public void Close()
        {
            if (Running)
            {
                base.Stop();
            }
            this.Dispose();
        }

        /// <summary>
        /// 接收数据
        /// </summary>
        /// <param name="session"></param>
        /// <param name="requestInfo"></param>
        void appServer_NewRequestReceived(ClientRequestPackSession session, BinaryRequestInfo requestInfo)
        {         
            //ActivedSession = session;
            //session.Charset = Encoding.UTF8;
            //ipAddress_Receive = session.RemoteEndPoint.ToString();
            //SetMessage("收到" + ipAddress_Receive + "数据: " + requestInfo.Key + " " + requestInfo.Body);
        }

        public void InitInterfaces(string inParamString)
        {
            listInitFailedInterfaces.Clear();
            foreach (KeyValuePair<string, IUpload> p in Uploaders)
            {             
                string outParams = "";
                IUpload uploader = p.Value;
                uploader.Login(inParamString, out outParams);
                if (!uploader.Inited)
                {
                    string info = string.Format("{0}初始化失败: {1}", uploader.InterfaceName, uploader.ErrorMessage);
                    Log.WriteAsync(info);
                    listInitFailedInterfaces.Add(new KeyValuePair<string, string>(uploader.InterfaceName, uploader.ErrorMessage));
                    OnInitFailed(uploader, uploader.ErrorMessage, "");
                }
                else
                {
                    OnInitOK(uploader, "");
                }
            }
        }

        public bool PostAll(string inParamString, out List<KeyValuePair<string, string>> listPostFailedInterfaces)
        {
            listPostFailedInterfaces = new List<KeyValuePair<string,string>>();
            foreach (KeyValuePair<string, IUpload> p in Uploaders)
            {
                string outParams = "";
                IUpload uploader = p.Value;
                bool bRet = uploader.Post(inParamString, out outParams);
                if (!bRet)
                {
                    string info = string.Format("{0}Post失败: {1}", uploader.InterfaceName, uploader.ErrorMessage);
                    Log.WriteAsync(info);
                    listPostFailedInterfaces.Add(new KeyValuePair<string, string>(uploader.InterfaceName, uploader.ErrorMessage));
                    OnPostFailed(uploader, uploader.ErrorMessage, "");
                }
                else
                {
                    OnPostOK(uploader, "");
                }
            }
            if(listPostFailedInterfaces.Count == 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        protected void OnInitOK(IUpload uploader, string outParams = "")
        {
            TransferResponsePackge pack = new TransferResponsePackge(uploader.InterfaceName, TransferAction.Login);
            pack.Success = true;
            pack.Result = TransferResult.LoginOK;
            pack.Message = "";
            pack.SetParams(outParams);
            ReportTransferReponse(pack);
        }

        protected void OnInitFailed(IUpload uploader, string reasonMsg, string outParams)
        {
            TransferResponsePackge pack = new TransferResponsePackge(uploader.InterfaceName, TransferAction.Login);
            pack.Success = false;
            pack.Result = TransferResult.LoginFailed;
            pack.Message = reasonMsg;
            pack.SetParams(outParams);
            ReportTransferReponse(pack);
        }

          protected void OnPostOK(IUpload uploader, string outParams = "")
        {
            TransferResponsePackge pack = new TransferResponsePackge(uploader.InterfaceName, TransferAction.Post);
            pack.Success = true;
            pack.Result = TransferResult.PostOK;
            pack.Message = "";
            pack.SetParams(outParams);
            ReportTransferReponse(pack);
        }

        protected void OnPostFailed(IUpload uploader, string reasonMsg, string outParams)
        {
            TransferResponsePackge pack = new TransferResponsePackge(uploader.InterfaceName, TransferAction.Post);
            pack.Success = false;
            pack.Result = TransferResult.PostFailed;
            pack.Message = reasonMsg;
            pack.SetParams(outParams);
            ReportTransferReponse(pack);
        }

        /// <summary>
        /// 检查初始化结果
        /// </summary>
        /// <returns></returns>
        public bool CheckInitResult(out string msg)
        {
            msg = "";
            if (listInitFailedInterfaces.Count > 0)
            {
                StringBuilder builder = new StringBuilder();
                for (int i = 0; i < listInitFailedInterfaces.Count; i++)
                {
                    builder.Append(listInitFailedInterfaces[i].Key);
                    builder.Append(":");
                    builder.Append(listInitFailedInterfaces[i].Value);
                }
                msg = builder.ToString();
                return false;
            }
            else
            {
                return true;
            }
        }

        public void ReleaseInterfaces(string inParamString)
        {
            foreach (KeyValuePair<string, IUpload> p in Uploaders)
            {
                IUpload uploader = p.Value;
                if (uploader != null && uploader.Inited)
                {
                    uploader.Logout();
                }              
            }
        }

        /// <summary>
        /// 当观测超时
        /// </summary>
        /// <param name="action"></param>
        /// <param name="msg"></param>
        public void OnWatchTimeout(ClientRequestPackSession session, IUpload uploader, string action, string msg)
        {
            TransferResponsePackge pack = new TransferResponsePackge(uploader.InterfaceName, action);
            pack.Success = false;
            pack.Message = msg;
            pack.Result = TransferResult.Timeout;
            ReportTransferReponse(pack);
            if (session.Connected)
            {
                session.Send(pack);
            }      
        }

        public void OnCatchException(ClientRequestPackSession session, IUpload uploader, string action, Exception ex)
        {
            TransferResponsePackge pack = new TransferResponsePackge(uploader.InterfaceName, action);
            pack.Success = false;
            pack.Message = ex.Message;
            pack.Result = TransferResult.CatchException;
            pack.SetParams("");
            ReportTransferReponse(pack);
            if (session.Connected)
            {
                session.Send(pack);
            }            
        }

        public void SendPackage(TransferResponsePackge pack)
        {
            if (ActivedSession != null && ActivedSession.Connected)
            {
                ActivedSession.Send(pack);
            }
        }
    }
}
